#pragma once

template<typename T>
bool CompareAndExchange(T* lvalue, const T& compare, const T& rvalue)
{
	if (*lvalue == compare)
	{
		*lvalue = rvalue;
		return true;
	}
	return false;
}

template<typename T>
T* CompareAndExchangeReturn(T* lvalue, const T& compare, const T& rvalue)
{
	return reinterpret_cast<T*>(InterlockedCompareExchange((LONG*)lvalue, (LONG)rvalue, (LONG)compare));
}

template<typename T>
bool CompareAndExchangeWeak(T* lvalue, const T& compare, const T& rvalue)
{
	T* prev = (T*) InterlockedCompareExchange((LONG*)lvalue, (LONG)rvalue, (LONG)compare);
	if (prev == lvalue)
	{
		return true;
	}
	lvalue = prev;
	return false;
}